#pragma once
#include "Runtime/CGI/DynamicCGI.h"
#include "VulkanDevice.h"
#include "VulkanViewport.h"
#include "Runtime/CGI/ClearValue.h"
#include "Runtime/Utils/SmartPtr.h"

namespace Alice{
    struct CGIVulkanRHIExternalImageDeleteCallbackInfo
    {
        void* UserData;
        void (*Function)(void* UserData);
    };
    class CGIVulkan: public DynamicCGI{
    public:
        uint32 mAPIVersion;
        VkInstance mVkInstance;
        VulkanDevice* mDevice;
        static CGIVulkan& Get(){ return *GetDynamicRHI<CGIVulkan>();}
        CGIVulkan();
        bool Init();
        SmartPtr<CGIViewport> CGICreateViewport(void* WindowHandle, uint32 SizeX, uint32 SizeY, bool bIsFullscreen, EPixelFormat PreferredPixelFormat);
        virtual SmartPtr<CGITexture> CGICreateTexture2DFromResource(EPixelFormat Format, uint32 SizeX, uint32 SizeY, uint32 NumMips, uint32 NumSamples, VkImage Resource, ETextureCreateFlags Flags,
            const FClearValueBinding& ClearValueBinding = FClearValueBinding::Transparent, const CGIVulkanRHIExternalImageDeleteCallbackInfo& ExternalImageDeleteCallbackInfo = {});
        SmartPtr<CGITexture> CGIGetViewportBackBuffer(CGIViewport* Viewport,uint32&inOutImageIndex);
        virtual ICGICommandContext* CGIGetDefaultContext();
        virtual CGIBuffer* RHICreateBuffer(CGICommandListBase& RHICmdList, CGIBufferDesc const& Desc, ECGIAccess ResourceState, CGIResourceCreateInfo& CreateInfo);
        virtual CGIGraphicsPipelineState* RHICreateGraphicsPipelineState(const FGraphicsPipelineStateInitializer& Initializer);
        // FlushType: Wait RHI Thread
        virtual CGIVertexShader* RHICreateVertexShader(const char*inShaderPath,unsigned char* inCode, int32 inCodeByteLen) override;
        // FlushType: Wait RHI Thread
        virtual CGIPixelShader* RHICreatePixelShader(const char*inShaderPath,unsigned char* inCode, int32 inCodeByteLen) override;
        virtual CGIVertexDeclaration* RHICreateVertexDeclaration(const VertexDeclarationElementList& Elements) override;
    };
}